package ffmpeg

import (
	"fmt"
	"gitee.com/bobo-rs/goffmpeg/utils"
	"path/filepath"
	"strings"
	"time"
)

type SFFmpeg struct {
	Driver  string
	EnvDir  string
	SaveDir string // 保存路径
}

const (
	defaultDriver = `ffmpeg` // 默认处理驱动
)

func New(envDir ...string) *SFFmpeg {
	// 获取环境变量
	envFFMpeg := utils.GetFFMpegEnv(envDir...)
	return &SFFmpeg{
		Driver: envFFMpeg + defaultDriver,
		EnvDir: envFFMpeg,
	}
}

// SrcDir 以源文件路径默认设置为保存路径
func (f *SFFmpeg) SrcDir(src string) (string, error) {
	var (
		dir, filename = filepath.Split(src)
		filenames     = strings.Split(filename, `.`)
	)
	// 以源文件路径默认设置为保存路径
	dir += filenames[0]
	if err := f.EnsureDir(dir); err != nil {
		return ``, err
	}
	return dir, nil
}

// SetSaveDir 设置保存目录
func (f *SFFmpeg) SetSaveDir(dir string) *SFFmpeg {
	f.SaveDir = dir
	return f
}

// outFile 输出文件路径
func (f *SFFmpeg) outFile(src, outExt, suffix string) (string, error) {
	var (
		_, filename = filepath.Split(src)
		filenames   = strings.Split(filename, `.`)
		dir         = f.SaveDir
	)
	// 直接保存路径
	if dir == `` {
		// 处理原文件路径
		saveDir, err := f.SrcDir(src)
		if err != nil {
			return "", err
		}
		dir = saveDir
	}
	// 输出路径是否为空
	if outExt == `` {
		outExt = f.Ext(src)
	}
	// 处理文件名
	return filepath.Join(dir, fmt.Sprintf(`%s_%s_%d.%s`, filenames[0], suffix, time.Now().Unix(), outExt)), nil
}

// Ext 不含.的文件后缀
func (f *SFFmpeg) Ext(dstFile string) string {
	return filepath.Ext(dstFile)[1:] // 不含.后缀
}

// ArgsMapping 命令参数映射列表
func (f *SFFmpeg) ArgsMapping() map[string][]string {
	return map[string][]string{
		`m3u8`: {`-c:v`, `libx264`, `-c:a`, `aac`, `-strict`, `-2`, `-f`, `hls`, `-hls_time`, `10`, `-hls_list_size`, `0`},
		`mp4`:  {`-c:v`, `libx264`, `-c:a`, `aac`},
		`avi`:  {`-c:v`, `mpeg4`, `-c:a`, `mp3`},
		`webm`: {`-c:v`, `libvpx`, `-c:a`, `libvorbis`},
		`mov`:  {`-c:v`, `qtrle`, `-c:a`, `pcm_s16le`},
		`mkv`:  {`-c`, ` copy`},
		`wmv`:  {`-c:v`, `wmv2`, `-c:a`, `wmav2`},
		`flv`:  {`-c:v`, `libx264`, `-c:a`, `aac`},
		`mpg`:  {`-c:v`, `mpeg2video`, `-c:a`, `mp2`},
		`ogg`:  {`-c:v`, `libtheora`, `-c:a`, `libvorbis`},
		`divx`: {`-c:v`, `libxvid`, `-c:a`, `libmp3lame`},
		`xvid`: {`-c:v`, `libxvid`, `-c:a`, `libmp3lame`},
		`mxf`:  {`-c:v`, `libx265`, `-c:a`, `pcm_s16le`},
	}
}

// processResults 处理结果集
func (f *SFFmpeg) processResults(results chan ChanResult) (outFiles []string, err error) {
	var errs []string
	// 迭代处理转换结果
	for result := range results {
		if result.Err != nil {
			errs = append(errs, result.Err.Error())
			continue
		}
		// 转换成功文件路径
		outFiles = append(outFiles, result.OutFile)
	}
	// 是否存在错误
	if len(errs) > 0 {
		err = fmt.Errorf(`视频转换错误：%s`, strings.Join(errs, `,`))
	}
	return outFiles, err
}
